package com.rx.core.enm;

import com.rx.core.base.RxBaseConstant;
import com.rx.core.handler.RxHandlerWraper;
import com.rx.core.mode.*;
import com.rx.core.util.EmptyChecker;
import com.rx.core.util.RxSpecialUtil;
import com.rx.core.util.RxUtil;

import java.lang.reflect.Field;
import java.util.*;

/**
 * 所有版权归 广西梧州 陈锦韬 所有
 *
 * @version V1.0
 * @Title: RX_LOG_MODE
 * @Package com.rx.core.enm
 * @Description: 日志打印模式
 * @author: 陈锦韬
 * @date: 2020\8\23 0023
 * @Copyright: 2020 陈锦韬  All rights reserved.
 */
public enum HANDLER_TYPE {
    /**
     * 不适合
     */
    NONE("NONE", null),
    /**
     * 适合所有请求
     */
    ALL("ALL", AllRequestHandlerContainer.class),
    /**
     * 单表详情查询
     */
    SINGLE_DETAIL("SINGLE_DETAIL", SingleDetailHandlerContainer.class),
    /**
     * 单表列表查询
     */
    SINGLE_LIST("SINGLE_LIST", SingleListHandlerContainer.class),

    /**
     * 单表分页查询
     */
    SINGLE_PAGE("SINGLE_PAGE", SinglePageHandlerContainer.class),

    /**
     * 单表逻辑删除
     */
    SINGLE_DELETE("SINGLE_DELETE", SingleDeleteHandlerContainer.class),

    /**
     * 单表新增
     */
    SINGLE_INSERT("SINGLE_INSERT", SingleInsertHandlerContainer.class),

    /**
     * 单表更新
     */
    SINGLE_UPDATE("SINGLE_UPDATE", SingleUpdateHandlerContainer.class),

    /**
     * 记录数
     */
    SINGLE_COUNT("SINGLE_COUNT", SingleCountHandlerContainer.class),

    /**
     * 最新记录
     */
    SINGLE_LATEST("SINGLE_LATEST", SingleLatestHandlerContainer.class),

    /**
     * 统计
     */
    SINGLE_STATIS("SINGLE_STATIS", SingleStatisHandlerContainer.class),

    /**
     * 批量插入
     */
    SINGLE_BATCH_INSERT("SINGLE_BATCH_INSERT", SingleBatchInsertHandlerContainer.class),

    /**
     * 批量更新
     */
    SINGLE_BATCH_UPDATE("SINGLE_BATCH_UPDATE", SingleBatchUpdateHandlerContainer.class),

    /**
     * 批量删除
     */
    SINGLE_BATCH_DELETE("SINGLE_BATCH_DELETE", SingleBatchDeleteHandlerContainer.class),

    /**
     * 批量更新
     */
    SINGLE_BATCH_SAVE("SINGLE_BATCH_SAVE", SingleBatchSaveHandlerContainer.class),

    /**
     * 无数据库操作
     */
    COMMON_NO_DB("COMMON_NO_DB", CommonNoDatabaseHandlerContainer.class),

    /**
     * 双表内连接
     */
    DOUBLE_LIST("DOUBLE_INNER_LIST", DoubleInnerListHandlerContainer.class),

    /**
     * 双表内连接联合
     */
    DOUBLE_UNION_LIST("DOUBLE_UNION_LIST", DoubleUnionInnerListHandlerContainer.class),

    /**
     * 双表内连接联合分页
     */
    DOUBLE_UNION_PAGE("DOUBLE_UNION_PAGE", DoubleUnionInnerPageHandlerContainer.class),

    /**
     * 双表左连接
     */
    DOUBLE_LEFT_LIST("DOUBLE_LEFT_LIST", DoubleLeftListHandlerContainer.class),

    /**
     * 双表内连接分页
     */
    DOUBLE_PAGE("DOUBLE_INNER_PAGE", DoubleInnerPageHandlerContainer.class),

    /**
     * 双表左连接分页
     */
    DOUBLE_LEFT_PAGE("DOUBLE_LEFT_PAGE", DoubleLeftPageHandlerContainer.class),
    /**
     * 双表插入
     */
    DOUBLE_INSERT("DOUBLE_INSERT", DoubleInsertHandlerContainer.class),
    /**
     * 拷贝插入
     */
    DOUBLE_COPY_INSERT("DOUBLE_COPY_INSERT", DoubleCopyHandlerContainer.class),

    /**
     * 双表内连接
     */
    THREE_LIST("THREE_INNER_LIST", ThreeInnerListHandlerContainer.class),

    THREE_LEFT_PAGE("THREE_LEFT_PAGE", ThreeInnerLeftPageHandlerContainer.class),
    ;
    String value;
    Class cls;
    ContainerMemmory containerMemmory;

    public static final String PATTERN = "PATTERN";
    public static final String URL_MODE = "URL_MODE";
    public static final String MEMMORY = "MEMMORY";

    HANDLER_TYPE(String value,Class cls) {
        this.value = value;
        if (null == cls){
            return;
        }
        this.cls = cls;
        this.containerMemmory =(ContainerMemmory) getFieldValue(this,MEMMORY);
    }
    public String getValue() {
        return value;
    }

    public Class getMapperClass(){
        return cls;
    }

    public ContainerMemmory memmory(){
        return this.containerMemmory;
    }

    public static HANDLER_TYPE[] getNormalTypes(){
        HANDLER_TYPE[] result = new HANDLER_TYPE[getNormalTypeSize()];
        int i = 0;
        for (HANDLER_TYPE handler_type : values()) {
            if (NONE != handler_type && ALL != handler_type){
                result[i] = handler_type;
                i++;
            }
        }
        return result;
    }
    public static int getNormalTypeSize(){
        return HANDLER_TYPE.values().length - 2;
    }
    public static HANDLER_TYPE enumByName(String value){
        for (HANDLER_TYPE handler_type : values()) {
            if (handler_type.getValue().equalsIgnoreCase(value)){
                return handler_type;
            }
        }
        return null;
    }
    public static Object getFieldValue(HANDLER_TYPE type,String fileName){
        if (NONE != type && ALL != type ){
            try {
                Field field = type.cls.getDeclaredField(fileName);
                field.setAccessible(true);
                return  field.get(null);
            } catch (NoSuchFieldException | IllegalAccessException e) {
                ;
            }
        }
        return null;
    }
    public static HANDLER_TYPE enumMatchUrl(String url){
        for (HANDLER_TYPE handler_type : values()) {
            String patternString = (String)getFieldValue(handler_type,PATTERN);
            if(EmptyChecker.isEmpty(patternString)){
                continue;
            }
            if(RxUtil.regCheck(patternString,url)){
                return handler_type;
            }
        }
        return null;
    }
    public static HANDLER_TYPE[] getNoneArray(){
        HANDLER_TYPE[] result = {HANDLER_TYPE.NONE};
        return result;
    }
    public static HANDLER_TYPE[] getExTypeList(HANDLER_TYPE[] exTypes){
        if (EmptyChecker.isEmpty(exTypes)){
            return null;
        }
        List<HANDLER_TYPE> resultList = getExTypeList(Arrays.asList(exTypes));
        HANDLER_TYPE[] result = new HANDLER_TYPE[resultList.size()];
        return resultList.toArray(result);
    }
    public static List<HANDLER_TYPE> getExTypeList(List<HANDLER_TYPE> exTypes){
        List<HANDLER_TYPE> resultList = new ArrayList<>();
        // 去除重复
        Set<HANDLER_TYPE> tmp = new HashSet<>(exTypes);
        if (HANDLER_TYPE.getNormalTypeSize() - tmp.size() <= 0){
            resultList.add(HANDLER_TYPE.NONE);
            return resultList;
        }

        for (HANDLER_TYPE value : HANDLER_TYPE.getNormalTypes()) {
            for (HANDLER_TYPE extype : tmp) {
                if (value != extype && null != value && null != extype){
                    // 将不是排除的类型放进数组
                    resultList.add(value);
                }
            }
        }
        return resultList;
    }

    public List<RxHandlerWraper> getHandlerListByAnno(String url,Class anno) throws Throwable {
        return (List<RxHandlerWraper>) RxSpecialUtil.AnnoForHandler(anno,
                ()->containerMemmory.getPrevHandler(url),
                ()->containerMemmory.getHandler(url),
                ()->containerMemmory.getAfterHandler(url));
    }

    public String getUrlByMode(String form){
        String urlMode = (String)getFieldValue(this,URL_MODE);
        return RxBaseConstant.STANDARD_API + urlMode.replace(RxBaseConstant.URL_FORM,form);
    }
    public String getUrlByMode(String mainForm,String secondForm){
        String urlMode = (String)getFieldValue(this,URL_MODE);
        urlMode = urlMode.replace(RxBaseConstant.URL_FORM,mainForm);
        urlMode = urlMode.replace(RxBaseConstant.URL_SERVER,secondForm);
        return RxBaseConstant.STANDARD_API + urlMode;
    }
}
